using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BaseLazySingleton<T> where T : new()
{
    private static T instance;

    private static readonly object lockObject = new object();

    public static T GetInstance()
    {
        lock (lockObject)
        {
            if (instance == null)
            {
                Debug.Log($"[Singleton] Create BaseLazySingleton : {typeof(T).ToString()} ");
                instance = new T();
            }
            return instance;
        }
    }
}

public class BaseHungrySingleton<T> where T : new()
{

    private static readonly T instance = new T();

    public static T GetInstance()
    {
        Debug.Log($"[Singleton] Create BaseHungrySingleton : {typeof(T).ToString()} ");
        return instance;
    }

}

public class BaseDoubleCheckSingleton <T> where T : new()
{

    private static T instance;

    private static readonly object lockObject = new object();

    public static T GetInstance()
    {

        if(instance == null)
        {
            lock (lockObject)
            {
                if (instance == null)
                {
                    Debug.Log($"[Singleton] Create BaseDoubleCheckSingleton : {typeof(T).ToString()} ");
                    instance = new T();
                }
            }
        }
        return instance;
    }

}

public class BaseSingletonAutoMono<T> : MonoBehaviour where T : MonoBehaviour
{

    private static T instance;
    
    public static T GetInstance()
    {
        if (instance == null)
        {
            GameObject obj = new GameObject();

            obj.name = typeof(T).ToString() + " (Singleton)";

            DontDestroyOnLoad(obj);

            Debug.Log($"[Singleton] Create SingletonAutoMono : {typeof(T).ToString()} ");
            instance = obj.AddComponent<T>();
        }
        
        return instance;
    } 
}
